/*! \file kru_rpt.c
	K&R Unit reporting facility.
*/

#include <assert.h>
#include <stdio.h>

#include "kru.h"
#include "_kru.h"

/*
	Collect the test's stats
 */
static void kru_test_collect_report(kru_test *self, kru_stat *stat)
{
	stat->registryTotalTests++;

	stat->testAsserts += self->asserts;
	stat->testSetups += self->setups;
	stat->testSetupSuccesses += self->setupSuccesses;
	stat->testSetupFailures += self->setupFailures;
	stat->testRuns += self->runs;
	stat->testSuccesses += self->successes;
	stat->testFailures += self->failures;
	stat->testTeardowns += self->teardowns;
	stat->testTeardownSuccesses += self->teardownSuccesses;
	stat->testTeardownFailures += self->teardownFailures;
	stat->registryRunTime += self->stop - self->start;
}

/*
	Collect the test suite's stats
 */
static void kru_suite_collect_report(kru_suite *self, kru_stat *stat)
{
	kru_test *currentTest;

	assert(NULL != self);
	assert(NULL != stat);

	stat->registryTotalSuites++;

	stat->suiteSetups += self->setups;
	stat->suiteSetupSuccesses += self->setupSuccesses;
	stat->suiteSetupFailures += self->setupFailures;
	stat->suiteRuns += self->runs;
	stat->suiteSuccesses += self->successes;
	stat->suiteFailures += self->failures;
	stat->suiteTeardowns += self->teardowns;
	stat->suiteTeardownSuccesses += self->teardownSuccesses;
	stat->suiteTeardownFailures += self->teardownSuccesses;

	currentTest = self->head;
	while(NULL != currentTest)
	{
		kru_test_collect_report(currentTest, stat);
		currentTest = currentTest->next;
	}
}

void kru_registry_print_report(kru_registry *self)
{
	kru_stat stat;
	kru_suite *current;

	assert(NULL != self);

	memset(&stat, 0, sizeof(stat));

	self->format("Collecing test results...\n");
	current = self->head;
	while(NULL != current)
	{
		kru_suite_collect_report(current, &stat);
		current = current->next;
	}

	self->format(
	"Total %d tests in %d suites run in %6.3f sec (not counting set ups/tear downs)\n"
	"Total %d suites set ups, %d successful and %d failed\n"
	"Total %d suites run, %d successful and %d failed\n"
	"Total %d suite tear downs, %d successful and %d failed\n"
	"Total %d test set ups, %d successful and %d failed\n"
	"Total %d tests run with total %d asserts, %d successful and %d failed\n"
	"Total %d test tear downs, %d successful and %d failed\n",
		stat.registryTotalTests,
		stat.registryTotalSuites,
		stat.registryRunTime / CLOCKS_PER_SEC,
		// Suite data
		stat.suiteSetups,
		stat.suiteSetupSuccesses,
		stat.suiteSetupFailures,
		stat.suiteRuns,
		stat.suiteSuccesses,
		stat.suiteFailures,
		stat.suiteTeardowns,
		stat.suiteTeardownSuccesses,
		stat.suiteTeardownFailures,
		// Test data
		stat.testSetups,
		stat.testSetupSuccesses,
		stat.testSetupFailures,
		stat.testRuns,
		stat.testAsserts,
		stat.testSuccesses,
		stat.testFailures,
		stat.testTeardowns,
		stat.testTeardownSuccesses,
		stat.testTeardownFailures);
}
